﻿using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Xml;
using SDT.ServiceSystem;

namespace URLChannelTester
{
    /// <summary>
    /// Written by TungNX
    /// </summary>
    public sealed partial class UrlCrawler 
    {
        static class Generator
        {

            private const string REGEX = @"\[x(\+(\d)+)*\]";

            internal static IList<string> GenUrls(string prefix, XmlNode n)
            {
                #region Page begin from Zero
                //Add Date : 28/10/2010
                //Author: TungNX
                //Check nex page =0
                if (IsStepsZero(n)) return GenUrlsFromZero(prefix, n);
                #endregion

                #region Analyse node's structure
                var pattern = n.InnerText.Trim();
                var from = n.Attributes["FromId"] != null ? Convert.ToInt32(n.Attributes["FromId"].Value) : 0;
                var to = n.Attributes["ToId"] != null ? Convert.ToInt32(n.Attributes["ToId"].Value) : 0;
                var loop = to == 0 ? Convert.ToInt32(n.Attributes["Loop"].Value) : to;
                to = to > 0 ? to : loop;
                #endregion
                #region if is format date
                if (IsPatternDate(pattern) != string.Empty)
                {
                    return GetStringFormatDate(prefix, n, IsPatternDate(pattern));
                }

                #endregion

                var l = new List<string>();
                var m = Regex.Match(pattern, REGEX);

                if (!m.Success)
                {
                    l.Add(pattern.StartsWith(prefix) ? pattern : string.Format("{0}{1}", prefix, pattern));
                }
                else
                {
                    var placeHolder = m.Value;

                    var nSteps = 1;
                    m = Regex.Match(placeHolder, @"\d+");
                    if (m.Success)
                        nSteps = Convert.ToInt32(m.Value);

                    for (int i = from; i < to; i++)
                    {
                        var url = String.Format("{0}{1}", prefix, pattern.Replace(placeHolder, ((i + (nSteps == 1 ? 1 : 0)) * nSteps).ToString()));
                        l.Add(url);
                    }
                }

                return l;
            }

            /// <summary>
            /// Author : TungNX
            /// Created Date : 28/10/2010
            /// </summary>
            /// <param name="prefix"></param>
            /// <param name="n"></param>
            /// <returns></returns>
            internal static IList<string> GenUrlsFromZero(string prefix, XmlNode n)
            {
                #region Analyse node's structure
                var pattern = n.InnerText.Trim();
                var from = n.Attributes["FromId"] != null ? Convert.ToInt32(n.Attributes["FromId"].Value) : 0;
                var to = n.Attributes["ToId"] != null ? Convert.ToInt32(n.Attributes["ToId"].Value) : 0;
                var loop = to == 0 ? Convert.ToInt32(n.Attributes["Loop"].Value) : to;
                to = to > 0 ? to : loop;
                #endregion

                string _REGEX = @"\[x(\-(\d)+)*\]";

                var l = new List<string>();
                var m = Regex.Match(pattern, _REGEX);

                if (!m.Success)
                {
                    l.Add(pattern.StartsWith(prefix) ? pattern : string.Format("{0}{1}", prefix, pattern));
                }
                else
                {
                    var placeHolder = m.Value;

                    var nSteps = 1;
                    m = Regex.Match(placeHolder, @"\d+");
                    if (m.Success)
                        nSteps = Convert.ToInt32(m.Value);

                    for (int i = from; i < to; i++)
                    {
                        var url = String.Format("{0}{1}", prefix, pattern.Replace(placeHolder,
                            ((i + (nSteps == 1 ? 1 : 0)) * nSteps).ToString()));
                        //Add is next page zero
                        if (i == 0)
                            url = String.Format("{0}{1}", prefix, pattern.Replace(placeHolder, i.ToString()));

                        l.Add(url);
                    }
                }

                return l;
            }

            private static string IsPatternDate(string pattern)
            {
                List<string> sList = new List<string> { "MM/dd/yyyy", "dd-MM-yyyy HH:mm:ss", "dd/MM/yyyy",
            "d-M-yyyy","yyyy-M-d","yyyy/M/d","d/M/yyyy","yyyy/MM/dd HH:mm:ss","yyyy-MM-dd HH-mm-ss","yyyy-MM-dd","dd-MM-yyyy","MM-dd-yyyy"};
                foreach (var s in sList)
                {
                    if (pattern.ToLower().Contains(s.ToLower()))
                        return s;
                }

                return string.Empty;
            }
            /// <summary>
            /// Create Date : 28/10/2010
            /// Kiem tra phan trang co bat dau tu trang 0
            /// </summary>
            /// <param name="n"></param>
            /// <returns></returns>
            private static bool IsStepsZero(XmlNode n)
            {
                string _REGEX = @"\[x(\-(\d)+)*\]";
                var pattern = n.InnerText.Trim();
                var m = Regex.Match(pattern, _REGEX);

                if (!m.Success) return false;
                return true;
            }

            internal static IList<string> GetStringFormatDate(string prefix, XmlNode n, string formatdate)
            {
                #region Analyse node's structure
                var pattern = n.InnerText.Trim();
                var from = n.Attributes["FromId"] != null ? Convert.ToInt32(n.Attributes["FromId"].Value) : 0;
                var to = n.Attributes["ToId"] != null ? Convert.ToInt32(n.Attributes["ToId"].Value) : 0;
                var loop = to == 0 ? Convert.ToInt32(n.Attributes["Loop"].Value) : to;
                to = to > 0 ? to : loop;
                #endregion
                #region Format date
                string _REGEX = @"\[x(\-(\d)+)*\]";
                #endregion
                pattern = pattern.ToLower().Replace(formatdate.ToLower(), "x");
                var l = new List<string>();
                var m = Regex.Match(pattern, _REGEX);

                if (!m.Success)
                {
                    l.Add(pattern.StartsWith(prefix) ? pattern : string.Format("{0}{1}", prefix, pattern));
                }
                else
                {
                    var placeHolder = m.Value;

                    var nSteps = 1;
                    m = Regex.Match(placeHolder, @"\d");

                    if (m.Success)
                        nSteps = Convert.ToInt32(m.Value);

                    for (int i = from; i < to; i++)
                    {
                        DateTime _dtNow = DateTime.Now.Date;
                        DateTime _dtTemp = _dtNow.AddDays((-1) * (i + (nSteps == 1 ? 1 : 0)) * nSteps);
                        //Modified date: 26/10/2010
                        if (i == 0) _dtTemp = _dtNow.AddDays(1).AddMinutes(-1);

                        var url = String.Format("{0}{1}", prefix, pattern.Replace(placeHolder, _dtTemp.ToString(formatdate)));
                        l.Add(url);
                    }
                }
                return l;

            }





        }
    }
}